/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "S_PhysicsNewTon.h"

#include <ppl.h>
#include "PxPhysicsAPI.h"

#include "物体/实现包含物体.h"
#include "../B_物理体/NewTon刚体.h"

#include "S_键值序列容器.h"

using namespace std;





struct S_NewTon : public S_Physics {
	S_NewTon核心	m_Core;

	S_NewTon();
	~S_NewTon();

	S_键值序列容器<uint32, NewtonBody*>	m_Body;



	void	f_Update();
	//void	f_Update车辆(S_Px车* 车);
	void	f_应用物理变换();



	void	f_取更新物体(std::vector<std::vector<Mat44f>>& mat, std::vector<std::vector<void*>>& userData);
	void	f_取更新物体(std::vector<Mat44f>& mat, std::vector<void*>& userData);
	void	f_等待更新结束();
	//S_物理体*	f_创建物理平面(vec4 location, uint32 key);
	void		f_添加物理体(S_物理体* body, uint32 scenekey);
	void		f_移除物理体(S_物理体* body, uint32 scenekey);



	//S_物理体*	f_add刚体(uint32 key);
	//void		f_add车辆(const S_三角Mesh& 车体, const S_车体参数& 车体参数, vector<S_物体*> 车轮, const vector<S_车轮参数>& 车轮参数);


};











S_NewTon::S_NewTon() {
	//场景默认场景
	
	
}

S_NewTon::~S_NewTon() {
	
}




void S_NewTon::f_Update() {
	//NewtonInverseDynamicsUpdate()
	//static float64 t = 0.0;
	//t += m_步进时间;
	NewtonUpdate(m_Core.m_物理世界, m_步进时间);
	//NewtonInverseDynamicsUpdate(m_Core.m_物理世界, )
}



/*void S_PhysX::f_Update车辆(S_Px车* 车) {
	
	if (车->m_是否手柄操作) {
		PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs(gPadSmoothingData, g转向前进速度表, 车->m_VehicleInputData, m_步进时间, gIsVehicleInAir, *车->m_车辆驱动);
	}
	else {
		PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs(gKeySmoothingData, g转向前进速度表, 车->m_VehicleInputData, m_步进时间, gIsVehicleInAir, *车->m_车辆驱动);
	}


	PxVehicleWheels* vehicles[1] = { 车->m_车辆驱动 };
	//PxVehicleSuspensionSweeps
	PxRaycastQueryResult* raycastResults = g车辆场景数据查询->getRaycastQueryResultBuffer(0);
	const PxU32 raycastResultsSize = g车辆场景数据查询->getQueryResultBufferSize();
	PxVehicleSuspensionRaycasts(g批量查询, 1, vehicles, raycastResultsSize, raycastResults);

	const PxVec3 grav = gScene->getGravity();
	PxWheelQueryResult wheelQueryResults[PX_MAX_NB_WHEELS];
	PxVehicleWheelQueryResult vehicleQueryResults[1] = { { wheelQueryResults, 车->m_车辆驱动->mWheelsSimData.getNbWheels() } };
	PxVehicleUpdates(m_步进时间, grav, *gFrictionPairs, 1, vehicles, vehicleQueryResults);


	gIsVehicleInAir = 车->m_车辆驱动->getRigidDynamicActor()->isSleeping() ? false : PxVehicleIsInAir(vehicleQueryResults[0]);

}*/



void S_NewTon::f_应用物理变换() {


}


void S_NewTon::f_取更新物体(vector<vector<Mat44f>>& mat, vector<vector<void*>>& userData) {
	

}


void S_NewTon::f_取更新物体(vector<Mat44f>& mat, vector<void*>& userData) {
	auto* bodys = m_Body.data();
	uint32 num = m_Body.size();

	mat.resize(mat.size() + num);
	userData.resize(userData.size() + num);
	auto* p_use = userData.data();
	auto* p_mat = mat.data();

	for (uint32 i = 0; i < num; ++i) {
	//Concurrency::parallel_for<uint32>(0, num, [&](uint32 i) {
		NewtonBodyGetMatrix(bodys[i], (float32*) & (p_mat[i]));
		vec3 pos;
		NewtonBodyGetPosition(bodys[i], (float32*)&pos);
		cout << "pos : x=" << pos.x << " y=" << pos.y << " z=" << pos.z << endl;
	//});
	}
}

void S_NewTon::f_等待更新结束() {
	
}







void S_NewTon::f_添加物理体(S_物理体* body, uint32 scenekey) {
	auto* nb = (NewtonBody*)(body->f_getBody());
	if (nb && m_Body.f_is存在(nb) == false) {
		uint32 id = m_Body.f_GenName(0);
		m_Body.f_add(nb, id);
	}
}

void S_NewTon::f_移除物理体(S_物理体* body, uint32 scenekey) {
	auto* nb = (NewtonBody*)(body->f_getBody());
	if (nb && m_Body.f_is存在(nb)) {
		uint32 id = m_Body[nb];
		m_Body.f_remove(id);
	}
}






//S_物理体* S_PhysX::f_创建物理平面(vec4 location, uint32 key) {
//	return new S_Px平面(m_PxCore.m_Physics, location, key);
	//m_Px场景s[0]->addActor(*plane->m_Plane);
//}

/*void S_PhysX::f_add车辆(const S_三角Mesh& 车体, const S_车体参数& 车体参数, vector<S_物体*> 车轮, const vector<S_车轮参数>& 车轮参数) {
	uint32 车轮数 = 车轮参数.size();

	S_Px车* px车 = new S_Px车(m_PxCore.m_Physics, m_PxCore.m_Cooking, 车体参数, 车轮数);

	S_模型* c车体 = dynamic_cast<S_模型*>(车体);
	px车->m_车体刚体->userData = c车体;

	auto mesh = c车体->f_get网格();
	px车->f_add构建车体(m_PxCore.m_Physics, m_PxCore.m_Cooking, mesh.f_Map顶点(), mesh.f_get顶点数量());

	for (uint32 i = 0; i < 车轮数; ++i) {
		S_Px车轮* px车轮 = new S_Px车轮(m_PxCore.m_Physics, m_PxCore.m_Cooking, 车轮参数[i]);
		//vec3 轮胎局部位置 = c车体->f_get位置();
		px车->f_add构建车轮(px车轮);
		px车轮->m_车轮形状->userData = 车轮[i];
		//px车->m_车轮.push_back(px车轮);
	}

	m_Px场景s[0]->addActor(*px车->m_车体刚体);

}*/

S_Physics* f_创建NewTon物理引擎() {
	return new S_NewTon();
}

S_物理几何体* f_NewTon长方体几何体(S_Physics* 解算器, const vec3& v) {
	auto& Core = dynamic_cast<S_NewTon*>(解算器)->m_Core;
	return new S_NewTon长方体几何体(&Core, v);
}

S_物理几何体* f_NewTon凸壳几何体(S_Physics* 解算器, const S_三角Mesh mesh) {
	auto& Core = dynamic_cast<S_NewTon*>(解算器)->m_Core;
	return new S_NewTon凸壳几何体(&Core, mesh);
}

S_物理体* f_NewTon刚体(S_Physics* 解算器, S_物理几何体& geom, S_物理材质& mat) {
	auto& Core = dynamic_cast<S_NewTon*>(解算器)->m_Core;
	return new S_NewTon刚体(&Core, geom, mat);
}

S_物理体* f_NewTon静态(S_Physics* 解算器, S_物理几何体& geom, S_物理材质& mat) {
	auto& Core = dynamic_cast<S_NewTon*>(解算器)->m_Core;
	return new S_NewTon刚体(&Core, geom, mat);
}




